#include "etcder.hpp"
#include "channel.hpp"
#include "friend.pb.h"
#include "base.pb.h"
#include "user.pb.h"
#include "message.pb.h"
#include "uuid.hpp"
#include <gflags/gflags.h>
#include <thread>
#include <gtest/gtest.h>
#include <iostream>
#include <string>
#include <vector>
#include <unordered_set>

DEFINE_bool(log_mode, false, "程序的运行模式: true-发布模式 false-调试模式");
DEFINE_string(log_file, "", "发布模式下，制定日志的输出文件");
DEFINE_int32(log_level, 0, "发布模式下，制定日志的输出等级");

DEFINE_string(etcd_host, "127.0.0.1:2379", "服务注册中心地址");
DEFINE_string(base_service, "/service", "服务监测根目录");

DEFINE_string(service, "/service/friend_service", "服务名称");

bite_im::ChannelPtr channel;

// 测试申请好友接口
// 陈志鸿向 陈庭鸿 陈钟 钟哥 ，陈钟向钟哥申请好友
void friend_apply1()
{
    bite_im::FriendService_Stub stub(channel.get());
    // 进行rpc调用

    bite_im::FriendAddReq req;

    req.set_request_id(bite_im::UUID::uuid());
    // 陈志鸿向陈庭鸿发出申请好友
    req.set_respondent_id("6771-9495-fdb4-0002");
    req.set_user_id("5d71-92bf-2176-0003");

    bite_im::FriendAddRsp resp;
    // 获取一个rpc操作对象
    brpc::Controller cntl;
    // stub调用我们实现的服务类ipml的接口
    stub.FriendAdd(&cntl, &req, &resp, nullptr);
}
void friend_apply2()
{
    bite_im::FriendService_Stub stub(channel.get());
    // 进行rpc调用

    bite_im::FriendAddReq req;

    req.set_request_id(bite_im::UUID::uuid());
    // 陈志鸿向陈钟发出申请好友
    req.set_respondent_id("3b70-49c7-dfe4-0004");
    req.set_user_id("5d71-92bf-2176-0003");

    bite_im::FriendAddRsp resp;
    // 获取一个rpc操作对象
    brpc::Controller cntl;
    // stub调用我们实现的服务类ipml的接口
    stub.FriendAdd(&cntl, &req, &resp, nullptr);
}
void friend_apply3()
{
    bite_im::FriendService_Stub stub(channel.get());
    // 进行rpc调用

    bite_im::FriendAddReq req;

    req.set_request_id(bite_im::UUID::uuid());
    // 陈志鸿向钟哥发出申请好友
    req.set_respondent_id("5b54-cf54-dfe7-0005");
    req.set_user_id("5d71-92bf-2176-0003");

    bite_im::FriendAddRsp resp;
    // 获取一个rpc操作对象
    brpc::Controller cntl;
    // stub调用我们实现的服务类ipml的接口
    stub.FriendAdd(&cntl, &req, &resp, nullptr);
}
void friend_apply4()
{
    bite_im::FriendService_Stub stub(channel.get());
    // 进行rpc调用

    bite_im::FriendAddReq req;

    req.set_request_id(bite_im::UUID::uuid());
    // 陈志鸿向钟哥发出申请好友
    req.set_respondent_id("5b54-cf54-dfe7-0005");
    req.set_user_id("3b70-49c7-dfe4-0004");

    bite_im::FriendAddRsp resp;
    // 获取一个rpc操作对象
    brpc::Controller cntl;
    // stub调用我们实现的服务类ipml的接口
    stub.FriendAdd(&cntl, &req, &resp, nullptr);
}
// 获取所有好友申请信息,和循环处理好友请求
// 陈庭鸿拒绝陈志鸿，其他都同意
void getAndDealApply1()
{
    bite_im::FriendService_Stub stub(channel.get());
    // 进行rpc调用

    bite_im::GetPendingFriendEventListReq req;

    req.set_request_id(bite_im::UUID::uuid());
    // 陈庭鸿获取所有申请列表
    req.set_user_id("6771-9495-fdb4-0002");

    bite_im::GetPendingFriendEventListRsp resp;
    // 获取一个rpc操作对象
    brpc::Controller cntl;
    // stub调用我们实现的服务类ipml的接口
    stub.GetPendingFriendEventList(&cntl, &req, &resp, nullptr);
    std::cout << "-------------------------好友申请处理----------------------------" << std::endl;
    std::cout << resp.event_size() << std::endl;
    for (int i = 0; i < resp.event_size(); i++)
    {
        auto event = resp.event(i);
        std::cout << "申请人为：" << event.sender().nickname() << std::endl;
        std::string line;
        std::cout << "是否同意好友申请：[yes/no]" << std::endl;
        std::getline(std::cin, line);
        bool agree = true;
        if (line != "yes")
        {
            agree = false;
        }
        // 处理好友申请
        bite_im::FriendAddProcessReq req1;

        req1.set_request_id(bite_im::UUID::uuid());
        // 陈庭鸿获取所有申请列表
        req1.set_user_id("6771-9495-fdb4-0002");
        req1.set_apply_user_id(event.sender().user_id());
        req1.set_notify_event_id(bite_im::UUID::uuid());
        req1.set_agree(agree);
        bite_im::FriendAddProcessRsp resp1;
        // 获取一个rpc操作对象
        brpc::Controller cntl1;
        // stub调用我们实现的服务类ipml的接口
        stub.FriendAddProcess(&cntl1, &req1, &resp1, nullptr);
    }
}
void getAndDealApply2()
{
    bite_im::FriendService_Stub stub(channel.get());
    // 进行rpc调用

    bite_im::GetPendingFriendEventListReq req;

    req.set_request_id(bite_im::UUID::uuid());
    // 陈钟获取所有申请列表
    req.set_user_id("3b70-49c7-dfe4-0004");

    bite_im::GetPendingFriendEventListRsp resp;
    // 获取一个rpc操作对象
    brpc::Controller cntl;
    // stub调用我们实现的服务类ipml的接口
    stub.GetPendingFriendEventList(&cntl, &req, &resp, nullptr);
    std::cout << "-------------------------好友申请处理----------------------------" << std::endl;
    for (int i = 0; i < resp.event_size(); i++)
    {
        auto event = resp.event(i);
        std::cout << "申请人为：" << event.sender().nickname() << std::endl;
        std::string line;
        std::cout << "是否同意好友申请：[yes/no]" << std::endl;
        std::getline(std::cin, line);
        bool agree = true;
        if (line != "yes")
        {
            agree = false;
        }
        // 处理好友申请
        bite_im::FriendAddProcessReq req1;

        req1.set_request_id(bite_im::UUID::uuid());
        req1.set_user_id("3b70-49c7-dfe4-0004");
        req1.set_apply_user_id(event.sender().user_id());
        req1.set_notify_event_id(bite_im::UUID::uuid());
        req1.set_agree(agree);
        bite_im::FriendAddProcessRsp resp1;
        // 获取一个rpc操作对象
        brpc::Controller cntl1;
        // stub调用我们实现的服务类ipml的接口
        stub.FriendAddProcess(&cntl1, &req1, &resp1, nullptr);
    }
}
void getAndDealApply3()
{
    bite_im::FriendService_Stub stub(channel.get());
    // 进行rpc调用

    bite_im::GetPendingFriendEventListReq req;

    req.set_request_id(bite_im::UUID::uuid());
    // 钟哥获取所有申请列表
    req.set_user_id("5b54-cf54-dfe7-0005");

    bite_im::GetPendingFriendEventListRsp resp;
    // 获取一个rpc操作对象
    brpc::Controller cntl;
    // stub调用我们实现的服务类ipml的接口
    stub.GetPendingFriendEventList(&cntl, &req, &resp, nullptr);
    std::cout << "-------------------------好友申请处理----------------------------" << std::endl;
    for (int i = 0; i < resp.event_size(); i++)
    {
        auto event = resp.event(i);
        std::cout << "申请人为：" << event.sender().nickname() << std::endl;
        std::string line;
        std::cout << "是否同意好友申请：[yes/no]" << std::endl;
        std::getline(std::cin, line);
        bool agree = true;
        if (line != "yes")
        {
            agree = false;
        }
        // 处理好友申请
        bite_im::FriendAddProcessReq req1;

        req1.set_request_id(bite_im::UUID::uuid());
        // 陈庭鸿获取所有申请列表
        req1.set_user_id("5b54-cf54-dfe7-0005");
        req1.set_apply_user_id(event.sender().user_id());
        req1.set_notify_event_id(bite_im::UUID::uuid());
        req1.set_agree(agree);
        bite_im::FriendAddProcessRsp resp1;
        // 获取一个rpc操作对象
        brpc::Controller cntl1;
        // stub调用我们实现的服务类ipml的接口
        stub.FriendAddProcess(&cntl1, &req1, &resp1, nullptr);
    }
}

// 此时好友关系为： 陈志鸿-陈钟 陈志鸿-钟哥 陈钟-钟哥
void getFriends1()
{
    bite_im::FriendService_Stub stub(channel.get());
    // 进行rpc调用

    bite_im::GetFriendListReq req;

    req.set_request_id(bite_im::UUID::uuid());
    // 陈志鸿获取好友列表
    req.set_user_id("5d71-92bf-2176-0003");

    bite_im::GetFriendListRsp resp;
    // 获取一个rpc操作对象
    brpc::Controller cntl;
    // stub调用我们实现的服务类ipml的接口
    stub.GetFriendList(&cntl, &req, &resp, nullptr);
    std::cout << "---------------------好友列表如下-----------------------" << std::endl;
    for (int i = 0; i < resp.friend_list_size(); i++)
    {
        auto user_info = resp.friend_list(i);
        std::cout << "好友为：" << user_info.nickname() << std::endl;
    }
}
void getFriends2()
{
    bite_im::FriendService_Stub stub(channel.get());
    // 进行rpc调用

    bite_im::GetFriendListReq req;

    req.set_request_id(bite_im::UUID::uuid());
    // 陈钟获取好友列表
    req.set_user_id("3b70-49c7-dfe4-0004");

    bite_im::GetFriendListRsp resp;
    // 获取一个rpc操作对象
    brpc::Controller cntl;
    // stub调用我们实现的服务类ipml的接口
    stub.GetFriendList(&cntl, &req, &resp, nullptr);
    std::cout << "---------------------好友列表如下-----------------------" << std::endl;
    for (int i = 0; i < resp.friend_list_size(); i++)
    {
        auto user_info = resp.friend_list(i);
        std::cout << "好友为：" << user_info.nickname() << std::endl;
    }
}
void getFriends3()
{
    bite_im::FriendService_Stub stub(channel.get());
    // 进行rpc调用

    bite_im::GetFriendListReq req;

    req.set_request_id(bite_im::UUID::uuid());
    // 钟哥获取好友列表
    req.set_user_id("5b54-cf54-dfe7-0005");

    bite_im::GetFriendListRsp resp;
    // 获取一个rpc操作对象
    brpc::Controller cntl;
    // stub调用我们实现的服务类ipml的接口
    stub.GetFriendList(&cntl, &req, &resp, nullptr);
    std::cout << "---------------------好友列表如下-----------------------" << std::endl;
    for (int i = 0; i < resp.friend_list_size(); i++)
    {
        auto user_info = resp.friend_list(i);
        std::cout << "好友为：" << user_info.nickname() << std::endl;
    }
}

// 测试删除好友 陈钟删除陈志鸿
void removeFriends()
{
    bite_im::FriendService_Stub stub(channel.get());
    // 进行rpc调用

    bite_im::FriendRemoveReq req;

    req.set_request_id(bite_im::UUID::uuid());
    // 陈钟获取好友列表
    req.set_user_id("3b70-49c7-dfe4-0004");
    req.set_peer_id("5d71-92bf-2176-0003");
    bite_im::FriendRemoveRsp resp;
    // 获取一个rpc操作对象
    brpc::Controller cntl;
    // stub调用我们实现的服务类ipml的接口
    stub.FriendRemove(&cntl, &req, &resp, nullptr);
}

// 用户搜索
void searchOther1()
{
    bite_im::FriendService_Stub stub(channel.get());
    // 进行rpc调用

    bite_im::FriendSearchReq req;

    req.set_request_id(bite_im::UUID::uuid());
    // 陈志鸿通过search获取其他列表
    req.set_user_id("5d71-92bf-2176-0003");
    req.set_search_key("陈");
    bite_im::FriendSearchRsp resp;
    // 获取一个rpc操作对象
    brpc::Controller cntl;
    // stub调用我们实现的服务类ipml的接口
    stub.FriendSearch(&cntl, &req, &resp, nullptr);
    std::cout << "---------------------好友列表如下-----------------------" << std::endl;
    for (int i = 0; i < resp.user_info_size(); i++)
    {
        auto info = resp.user_info(i);
        std::cout << "用户为：" << info.nickname() << std::endl;
    }
}
void searchOther2()
{
    bite_im::FriendService_Stub stub(channel.get());
    // 进行rpc调用

    bite_im::FriendSearchReq req;

    req.set_request_id(bite_im::UUID::uuid());
    // 陈庭鸿通过search获取其他列表
    req.set_user_id("6771-9495-fdb4-0002");
    req.set_search_key("陈");
    bite_im::FriendSearchRsp resp;
    // 获取一个rpc操作对象
    brpc::Controller cntl;
    // stub调用我们实现的服务类ipml的接口
    stub.FriendSearch(&cntl, &req, &resp, nullptr);
    std::cout << "---------------------好友列表如下-----------------------" << std::endl;
    for (int i = 0; i < resp.user_info_size(); i++)
    {
        auto info = resp.user_info(i);
        std::cout << "用户为：" << info.nickname() << std::endl;
    }
}

// 陈志鸿创建群聊
void buildGroupChat()
{
    bite_im::FriendService_Stub stub(channel.get());
    // 进行rpc调用

    bite_im::ChatSessionCreateReq req;

    req.set_request_id(bite_im::UUID::uuid());
    // 陈庭鸿通过search获取其他列表
    req.set_user_id("5d71-92bf-2176-0003");
    req.set_chat_session_name("同一个人");
    req.add_member_id_list("5d71-92bf-2176-0003");
    req.add_member_id_list("3b70-49c7-dfe4-0004");
    req.add_member_id_list("6771-9495-fdb4-0002");
    req.add_member_id_list("5b54-cf54-dfe7-0005");
    bite_im::ChatSessionCreateRsp resp;
    // 获取一个rpc操作对象
    brpc::Controller cntl;
    // stub调用我们实现的服务类ipml的接口
    stub.ChatSessionCreate(&cntl, &req, &resp, nullptr);
}

// 钟哥获取聊天会话列表
void getChatSessionList()
{
    bite_im::FriendService_Stub stub(channel.get());
    // 进行rpc调用

    bite_im::GetChatSessionListReq req;

    req.set_request_id(bite_im::UUID::uuid());
    req.set_user_id("5b54-cf54-dfe7-0005");

    bite_im::GetChatSessionListRsp resp;
    // 获取一个rpc操作对象
    brpc::Controller cntl;
    // stub调用我们实现的服务类ipml的接口
    stub.GetChatSessionList(&cntl, &req, &resp, nullptr);
    std::cout << "---------------------聊天列表如下-----------------------" << std::endl;
    for (int i = 0; i < resp.chat_session_info_list_size(); i++)
    {
        auto info_list = resp.chat_session_info_list(i);
        std::cout << "会话名称为：" << info_list.chat_session_name()<< ", 会话头像为：" << info_list.avatar() << std::endl;
        // 当前测试发送信息为为string_message
        std::cout << "会话消息为：" << info_list.prev_message().message().string_message().content() << std::endl;
    }
}

// 搜索群聊成员
void getChatSessionMember()
{
    bite_im::FriendService_Stub stub(channel.get());
    // 进行rpc调用

    bite_im::GetChatSessionMemberReq req;

    req.set_request_id(bite_im::UUID::uuid());
    // 场景：在前端，我们在某个群聊中点击获取全部成员！！！
    req.set_chat_session_id("69d5-5bc3-12ce-0001");

    bite_im::GetChatSessionMemberRsp resp;
    // 获取一个rpc操作对象
    brpc::Controller cntl;
    // stub调用我们实现的服务类ipml的接口
    stub.GetChatSessionMember(&cntl, &req, &resp, nullptr);
    std::cout << "---------------------聊天成员如下-----------------------" << std::endl;
    for (int i = 0; i < resp.member_info_list_size(); i++)
    {
        auto member = resp.member_info_list(i);
        std::cout << "用户名称为：" << member.nickname() << ", 用户头像为：" << member.avatar()<< std::endl;
    }
}


int main(int argc, char *argv[])
{
    testing::InitGoogleTest(&argc, argv);
    google::ParseCommandLineFlags(&argc, &argv, true);
    bite_im::initLogger(FLAGS_log_mode, FLAGS_log_file, FLAGS_log_level);
    auto manager = std::make_shared<bite_im::ServiceManager>();
    manager->declareService(FLAGS_service);
    // 构造服务发现对象
    auto put_cb = std::bind(&bite_im::ServiceManager::onServiceOnline, manager.get(),
                            std::placeholders::_1, std::placeholders::_2);
    auto del_cb = std::bind(&bite_im::ServiceManager::onServiceOffLine, manager.get(),
                            std::placeholders::_1, std::placeholders::_2);
    auto discoverer = std::make_shared<bite_im::Discovery>(FLAGS_base_service, FLAGS_etcd_host, put_cb, del_cb);

    // 获取服务信道
    channel = manager->choose(FLAGS_service);
    if (channel.get() == nullptr)
    {
        return -1;
    }
    // 我们直接在测试样例中创建Service服务存根

    // friend_apply1();
    // friend_apply2();
    // friend_apply3();
    // friend_apply4();

    // getAndDealApply1();
    // getAndDealApply2();
    // getAndDealApply3();

    // getFriends1();
    // getFriends2();
    // getFriends3();

    // removeFriends();
    // std::this_thread::sleep_for(std::chrono::seconds(1));

    // searchOther1();
    // searchOther2();
    // std::this_thread::sleep_for(std::chrono::seconds(1));

    // // buildGroupChat();
    // std::this_thread::sleep_for(std::chrono::seconds(1));

    // getChatSessionMember();

    getChatSessionList();
    return RUN_ALL_TESTS();
}